package com.house365.core.image;

import java.io.FileInputStream;
import java.io.FilterInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.lang.ref.WeakReference;
import java.net.MalformedURLException;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.Queue;
import java.util.Stack;
import java.util.WeakHashMap;

import org.apache.http.client.ClientProtocolException;

import android.app.Activity;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Bitmap.Config;
import android.graphics.BitmapFactory;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.Looper;
import android.os.Message;
import android.widget.ImageView;

import com.house365.core.application.BaseApplication;
import com.house365.core.constant.CorePreferences;
import com.house365.core.util.FileUtil;
import com.house365.core.util.store.DiskCache;
import com.house365.core.util.store.IOUtil;

/**
 * 
 * @author Rick
 * 
 */
public class AsyncImageLoader {

	public int IMAGE_MAX_SIZE = 480;
	private final int IMAGE_MAX_SCALE = 4;
	private final int IMAGE_MIDDLE_SCALE = 2;
	private final int IMAGE_HIGH_SCALE = 1;
	public static final int IMAGE_SCALE_TYPE_HIGH = 1;
	public static final int IMAGE_SCALE_TYPE_MIDDLE = 4;
	public static final int IMAGE_SCALE_TYPE_LOW =8;
	public static final int IMAGE_SCALE_TYPE_NONE = -1;

	private WeakHashMap<String, WeakReference<Bitmap>> imageCache;

	private DiskCache mDiskCache;
	private Context context;
	private BaseApplication application;

	public AsyncImageLoader(Context context) {
		imageCache = new WeakHashMap<String, WeakReference<Bitmap>>();
		application = (BaseApplication) ((Activity) context).getApplication();
		mDiskCache = application.getDiskCache();
		this.context = context;
		if (application.getMetrics() != null
				&& application.getMetrics().widthPixels > IMAGE_MAX_SIZE) {
			IMAGE_MAX_SIZE = application.getMetrics().widthPixels;
		}

	}

	public BaseApplication getApplication() {
		return application;
	}

	public void setApplication(BaseApplication application) {
		this.application = application;
	}

	/**
	 * load Image from localFile，but set two level cache:memory，disk
	 * 
	 * @param localFile
	 * @param imageCallback
	 * @param scaleType
	 * @return
	 */
	public void loadDrawableByLocalFile(final ImageView imageView,
			final String localFile, final ImageViewLoadListener imageCallback,
			final int scaleType) {
		if (imageView == null) {
			return;
		}
//		if (imageView.getTag() != null
//				&& imageView.getTag().toString().equals(localFile)) {
//			return;
//		}
		if (localFile == null || localFile.equals("")) {
			return;
		}
		// 添加url tag
		imageView.setTag(localFile);

		int w = imageView.getWidth();
		int h = imageView.getHeight();
		if (w <= 0) {
			w = -1;
		}
		if (h <= 0) {
			h = -1;
		}
		final Handler handler = new Handler() {
			public void handleMessage(Message message) {
				if (message.what == 0) {
					imageCallback.imageLoaded((Bitmap) message.obj, localFile);
				} else if (message.what == 1) {
					imageCallback.imageLoading();
				} else {
					imageCallback.imageLoadedFailure();
				}

			}
		};

		// first scan BitMap from memory
		if (imageCache.containsKey(localFile)) {
			WeakReference<Bitmap> softReference = imageCache.get(localFile);
			Bitmap bitmap = softReference.get();
			if (bitmap != null && !bitmap.isRecycled()) {
				// call back
				Message message = handler.obtainMessage(0, bitmap);
				handler.sendMessage(message);
				return;
			} else {
				imageCache.remove(localFile);
			}
		}

		Message message = handler.obtainMessage(1, null);
		handler.sendMessage(message);
		queueImage(new ImageRef(imageView, localFile, scaleType, w, h, handler,
				false));

	}

	/** 图片加载队列，后进先出 */
	private Stack<ImageRef> mImageQueue = new Stack<ImageRef>();

	/** 图片请求队列，先进先出，用于存放已发送的请求。 */
	private Queue<ImageRef> mRequestQueue = new LinkedList<ImageRef>();
	/** 图片加载线程消息处理器 */
	private Handler mImageLoaderHandler;

	/** 图片加载线程是否就绪 */
	private boolean mImageLoaderIdle = true;

	/** 请求图片 */
	private static final int MSG_REQUEST = 1;
	/** 图片加载完成 */
	private static final int MSG_REPLY = 2;
	/** 中止图片加载线程 */
	private static final int MSG_STOP = 3;

	/**
	 * 存放图片信息
	 */
	class ImageRef {

		ImageView imageView;
		String url;
		int scaleType;
		int width = 0;
		int height = 0;
		Handler handler;
		boolean fromNet;

		public ImageRef(ImageView imageView, String url, int scaleType,
				int width, int height, Handler handler, boolean fromNet) {
			super();
			this.imageView = imageView;
			this.url = url;
			this.scaleType = scaleType;
			this.width = width;
			this.height = height;
			this.handler = handler;
			this.fromNet = fromNet;
		}

	}

	/**
	 * 入队，后进先出
	 * 
	 * @param imageRef
	 */
	public synchronized void queueImage(ImageRef imageRef) {

		// 删除已有ImageView
		try {
			Iterator<ImageRef> iterator = mImageQueue.iterator();
		
			while (iterator.hasNext()) {
				ImageRef t= iterator.next();
				if (t.imageView == imageRef.imageView) {
					iterator.remove();
				}
			}
		} catch (Exception e) {
			CorePreferences.ERROR(e);
		}

		// 添加请求
		mImageQueue.push(imageRef);
		sendRequest();
	}

	/**
	 * 发送请求
	 */
	private void sendRequest() {

		// 开启图片加载线程
		if (mImageLoaderHandler == null) {
			HandlerThread imageLoader = new HandlerThread("image_loader");
			imageLoader.start();
			mImageLoaderHandler = new ImageLoaderHandler(
					imageLoader.getLooper());
		}

		// 发送请求
		if (mImageLoaderIdle && mImageQueue.size() > 0) {
			ImageRef imageRef = mImageQueue.pop();
			Message message = mImageLoaderHandler.obtainMessage(MSG_REQUEST,
					imageRef);
			mImageLoaderHandler.sendMessage(message);
			mImageLoaderIdle = false;
			mRequestQueue.add(imageRef);
		}
	}

	/**
	 * 图片加载线程
	 */
	class ImageLoaderHandler extends Handler {
		public ImageLoaderHandler(Looper looper) {
			super(looper);
		}

		public void handleMessage(Message msg) {
			if (msg == null) {
				return;
			}
			switch (msg.what) {
			case MSG_REQUEST: // 收到请求
				Bitmap bitmap = null;
				if (msg.obj != null && msg.obj instanceof ImageRef) {
					ImageRef imageRef = (ImageRef) msg.obj;
					final String url = imageRef.url;
					if (url == null) {
						return;
					}
					try {
						if (imageRef.fromNet) {
							// first scan Bitmap from Disk
							if (mDiskCache.exists(url)) {
								bitmap = getBitMapFromStream(
										new BitMapInputStream() {

											@Override
											public InputStream getInputStream()
													throws IOException {
												return mDiskCache
														.getInputStream(url);
											}
										}, imageRef.width, imageRef.height,
										imageRef.scaleType);
								if (bitmap != null && !bitmap.isRecycled()) {
									imageCache.put(url,
											new WeakReference<Bitmap>(bitmap));
								}

							} else {
								// second,load Bitmap from URL
								bitmap = loadImageFromUrl(url, imageRef.width,
										imageRef.height, imageRef.scaleType);
								
							}
						} else {
							// second,load Bitmap from File System
							bitmap = getBitMapFromStream(
									new BitMapInputStream() {

										@Override
										public InputStream getInputStream()
												throws IOException {
											return new FileInputStream(url);
										}
									}, imageRef.width, imageRef.height,
									imageRef.scaleType);
							imageCache.put(url, new WeakReference<Bitmap>(
									bitmap));

						}
					} catch (Exception e) {
						Message message = imageRef.handler.obtainMessage(2,
								null);
						imageRef.handler.sendMessage(message);
						CorePreferences.ERROR("", e);
					}
				}

				if (mImageManagerHandler != null) {
					Message message = mImageManagerHandler.obtainMessage(
							MSG_REPLY, bitmap);
					mImageManagerHandler.sendMessage(message);
				}
				break;

			case MSG_STOP: // 收到终止指令
				Looper.myLooper().quit();
				break;

			}
		}
	}

	/** UI线程消息处理器 */
	private Handler mImageManagerHandler = new Handler() {

		@Override
		public void handleMessage(Message msg) {
			if (msg != null) {
				switch (msg.what) {

				case MSG_REPLY: // 收到应答

					do {
						if (mRequestQueue.isEmpty()) {
							break;
						}
						ImageRef imageRef = mRequestQueue.remove();

						if (imageRef == null)
							break;

						if (imageRef.imageView == null
								|| imageRef.imageView.getTag() == null
								|| imageRef.url == null)
							break;

						if (!(msg.obj instanceof Bitmap) || msg.obj == null) {
							break;
						}
						Bitmap bitmap = (Bitmap) msg.obj;

						// 非同一ImageView
						if (!(imageRef.url).equals((String) imageRef.imageView
								.getTag())) {
							break;
						}

						Message message = imageRef.handler.obtainMessage(0,
								bitmap);
						imageRef.handler.sendMessage(message);

					} while (false);

					break;
				}
			}
			// 设置闲置标志
			mImageLoaderIdle = true;

			// 若服务未关闭，则发送下一个请求。
			if (mImageLoaderHandler != null) {
				sendRequest();
			}
		}
	};

	/**
	 * load Image from url，but set two level cache:memory，disk
	 * 
	 * @param imageUrl
	 * @param imageCallback
	 * @param scaleType
	 * @return
	 */
	public void loadDrawable(final ImageView imageView, final String imageUrl,
			final ImageViewLoadListener imageCallback, final int scaleType) {
		if (imageView == null) {
			return;
		}
		// if (imageView.getTag() != null
		// && imageView.getTag().toString().equals(imageUrl)) {
		// return;
		// }
		if (imageUrl == null || imageUrl.equals("")) {
			return;
		}
		final Handler handler = new Handler() {
			public void handleMessage(Message message) {
				if (message.what == 0) {
					imageCallback.imageLoaded((Bitmap) message.obj, imageUrl);
				} else if (message.what == 1) {
					imageCallback.imageLoading();
				} else {
					imageCallback.imageLoadedFailure();
				}

			}
		};
		new Thread() {
			@Override
			public void run() {

				// 添加url tag
				imageView.setTag(imageUrl);

				int w = imageView.getWidth();
				int h = imageView.getHeight();
				if (w <= 0) {
					w = -1;
				}
				if (h <= 0) {
					h = -1;
				}

				// first scan BitMap from memory
				if (imageCache.containsKey(imageUrl)) {
					WeakReference<Bitmap> softReference = imageCache
							.get(imageUrl);
					Bitmap bitmap = softReference.get();
					if (bitmap != null && !bitmap.isRecycled()) {
						// call back
						Message message = handler.obtainMessage(0, bitmap);
						handler.sendMessage(message);
						return;
					} else {
						imageCache.remove(imageUrl);
					}
				}

				Message message = handler.obtainMessage(1, null);
				handler.sendMessage(message);
				queueImage(new ImageRef(imageView, imageUrl, scaleType, w, h,
						handler, true));
			}
		}.start();

	}
	
	/**
	 * async load bitmap from URL,just return bitmap
	 * @param imageUrl
	 * @param imageCallback
	 * @param scaleType
	 * @return
	 */
	public Bitmap loadDrawableFromUrl(final String imageUrl,
			final ImageViewLoadListener imageCallback,final int scaleType) {
		//scan from memeory
		if (imageCache.containsKey(imageUrl)) {
			WeakReference<Bitmap> softReference = imageCache.get(imageUrl);
			Bitmap bitmap = softReference.get();
			if (bitmap != null && !bitmap.isRecycled()) {
				return bitmap;
			}else{
				imageCache.remove(imageUrl);
			}
		} 
		//scan from disk
		if(mDiskCache.exists(imageUrl)){
			try {
				Bitmap bitmap = getBitMapFromStream(new BitMapInputStream() {

					@Override
					public InputStream getInputStream() throws IOException {
						return mDiskCache.getInputStream(imageUrl);
					}
				},-1,-1,scaleType);;
				if(bitmap!=null && !bitmap.isRecycled()){
					imageCache.put(imageUrl, new WeakReference<Bitmap>(bitmap));
					return bitmap;
				}
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		final Handler handler = new Handler() {
			public void handleMessage(Message message) {
				if (message.what == 0) {
					imageCallback.imageLoaded((Bitmap) message.obj, imageUrl);
				} else if (message.what == 1) {
					imageCallback.imageLoading();
				} else {
					imageCallback.imageLoadedFailure();
				}

			}
		};
		handler.sendMessage(handler.obtainMessage(1));
		new Thread() {
			@Override
			public void run() {
				Bitmap bitmap = loadImageFromUrl(imageUrl, -1, -1, scaleType);
				Message message ;
				if(bitmap != null){
					message= handler.obtainMessage(0, bitmap);
				}else{
					message = handler.obtainMessage(2,null);
				}
				
				handler.sendMessage(message);
			}
		}.start();
		return null;
	}

	/**
	 * async load bitmap from file system,just return bitmap
	 * @param localFile
	 * @param imageCallback
	 * @param scaleType
	 * @return
	 */
	public Bitmap loadDrawableFromLocalFile(final String localFile,
			final ImageViewLoadListener imageCallback,final int scaleType) {
		//scan from memeory
				if (imageCache.containsKey(localFile)) {
					WeakReference<Bitmap> softReference = imageCache.get(localFile);
					Bitmap bitmap = softReference.get();
					if (bitmap != null && !bitmap.isRecycled()) {
						return bitmap;
					}else{
						imageCache.remove(localFile);
					}
				} 
				final Handler handler = new Handler() {
					public void handleMessage(Message message) {
						if (message.what == 0) {
							imageCallback.imageLoaded((Bitmap) message.obj, localFile);
						} else if (message.what == 1) {
							imageCallback.imageLoading();
						} else {
							imageCallback.imageLoadedFailure();
						}

					}
				};
				handler.sendMessage(handler.obtainMessage(1));
				new Thread() {
					@Override
					public void run() {
						// load Bitmap from File System
						Bitmap bitmap=null;
						try {
							bitmap = getBitMapFromStream(
									new BitMapInputStream() {

										@Override
										public InputStream getInputStream()
												throws IOException {
											return new FileInputStream(localFile);
										}
									}, -1,-1,
									scaleType);
						} catch (IOException e) {
							CorePreferences.ERROR("",e);
						}
						
						Message message ;
						if(bitmap != null){
							imageCache.put(localFile, new WeakReference<Bitmap>(
									bitmap));
							message= handler.obtainMessage(0, bitmap);
						}else{
							message = handler.obtainMessage(2,null);
						}
						
						handler.sendMessage(message);
					}
				}.start();
				return null;
	}
	
	public Bitmap getBitmapFromLocalFile(final String localFile,
			final int scaleType) {
		//scan from memeory
				if (imageCache.containsKey(localFile)) {
					WeakReference<Bitmap> softReference = imageCache.get(localFile);
					Bitmap bitmap = softReference.get();
					if (bitmap != null && !bitmap.isRecycled()) {
						return bitmap;
					}else{
						imageCache.remove(localFile);
					}
				} 
						// load Bitmap from File System
						Bitmap bitmap=null;
						try {
							bitmap = getBitMapFromStream(
									new BitMapInputStream() {

										@Override
										public InputStream getInputStream()
												throws IOException {
											return new FileInputStream(localFile);
										}
									}, -1,-1,
									scaleType);
						} catch (IOException e) {
							CorePreferences.ERROR("",e);
						}
						if(bitmap != null){
							imageCache.put(localFile, new WeakReference<Bitmap>(
									bitmap));
						}
						return bitmap;
	}
	

	/**
	 * get a bitmap from url
	 * 
	 * @param url
	 * @param w
	 * @param h
	 * @param scaleType
	 * @return
	 */
	public Bitmap loadImageFromUrl(final String url, int w, int h, int scaleType) {
		Bitmap b = null;
		InputStream is = null;
		try {
			is = application.getApi().getWithStream(url, null);
			if (mDiskCache.aviable()) {
				mDiskCache.store(url, new FlushedInputStream(is));
				b = getBitMapFromStream(new BitMapInputStream() {

					@Override
					public InputStream getInputStream() throws IOException {
						return mDiskCache.getInputStream(url);
					}
				}, w, h, scaleType);
			} else {
				final InputStream is2 = is;
				b = getBitMapFromStream(new BitMapInputStream() {

					@Override
					public InputStream getInputStream() throws IOException {
						// TODO Auto-generated method stub
						return is2;
					}
				}, w, h, scaleType);
			}
			imageCache.put(url, new WeakReference<Bitmap>(
					b));
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			try {
				if (is != null) {
					is.close();
				}
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		return b;
	}

	static class FlushedInputStream extends FilterInputStream {
		public FlushedInputStream(InputStream inputStream) {
			super(inputStream);
		}

		@Override
		public long skip(long n) throws IOException {
			long totalBytesSkipped = 0L;
			while (totalBytesSkipped < n) {
				long bytesSkipped = in.skip(n - totalBytesSkipped);
				if (bytesSkipped == 0L) {
					int b = read();
					if (b < 0) {
						break; // we reached EOF
					} else {
						bytesSkipped = 1; // we read one byte
					}
				}
				totalBytesSkipped += bytesSkipped;
			}
			return totalBytesSkipped;
		}
	}

	/**
	 * clear image cache,we suggest do this when page is destroy.
	 */
	public void clearCacheImage() {
		// 清空请求队列
		mImageQueue.clear();
		Iterator<WeakReference<Bitmap>> it = imageCache.values().iterator();
		while (it.hasNext()) {
			WeakReference<Bitmap> softReference = it.next();
			if (softReference.get() != null) {
				softReference.get().recycle();
				softReference.clear();
			}
		}
		imageCache.clear();
	}

	/**
	 * destroy a Bitmap.
	 * 
	 * @param imageUrl
	 */
	public void invalidate(String imageUrl) {
		WeakReference<Bitmap> softReference = imageCache.get(imageUrl);
		if (softReference != null && softReference.get() != null) {
			softReference.get().recycle();
			softReference.clear();
		}
		imageCache.remove(imageUrl);
		if (mDiskCache.exists(imageUrl)) {
			mDiskCache.invalidate(imageUrl);
		}
	}

	/**
	 * getBitMapFromStream
	 * 
	 * @param inputStream
	 * @param w
	 *            ,the width of actually view
	 * @param h
	 *            ,the height of actually view
	 * @param scaleType
	 * @return
	 * @throws IOException
	 */
	public Bitmap getBitMapFromStream(BitMapInputStream inputStream, int w,
			int h, int scaleType) throws IOException {
		Bitmap bitmap = null;
		try {
			byte[] data = IOUtil.toByteArray(inputStream.getInputStream());

			if (data != null) {
				BitmapFactory.Options opts = new BitmapFactory.Options();
				opts.inJustDecodeBounds = true;
				BitmapFactory.decodeByteArray(data, 0, data.length, opts);
				int inSampleSize = computeSampleSize(opts,
						(w <= 0 && h <= 0) ? -1 : Math.min(w, h),
						(w <= 0 && h <= 0) ? -1 : w * h, scaleType);
				CorePreferences.DEBUG("[AsyncImageLoader.inSampleSize]"
						+ inSampleSize);
				opts.inSampleSize = inSampleSize;
				opts.inJustDecodeBounds = false;
				opts.inPreferredConfig = Config.RGB_565;
				bitmap = BitmapFactory.decodeByteArray(data, 0, data.length,
						opts);
			}
		} catch (OutOfMemoryError e) {
			e.printStackTrace();
			System.gc();
		}
		return bitmap;
	}
	
	/**
	 * compute scale factor.
	 * 
	 * @param options
	 * @param minSideLength
	 * @param maxNumOfPixels
	 * @return
	 */
	public int computeSampleSize(BitmapFactory.Options options,
			int minSideLength, int maxNumOfPixels, int scaleType) {
		int initialSize = computeInitialSampleSize(options, minSideLength,
				maxNumOfPixels);

		int roundedSize;
		if (initialSize <= 8) {
			roundedSize = 1;
			while (roundedSize < initialSize) {
				roundedSize <<= 1;
			}
		} else {
			roundedSize = (initialSize + 7) / 8 * 8;
		}
		// if user trans a parameter of IMAGE SCALE TYPE,
		// we should make sure the sample size is less than the parameter
	
		
		if(minSideLength ==-1 && maxNumOfPixels ==-1){
			if (scaleType == IMAGE_SCALE_TYPE_LOW ) {
				double w = options.outWidth;
				double h = options.outHeight;
				if (roundedSize > IMAGE_MAX_SCALE ) {
					roundedSize = IMAGE_MAX_SCALE;
				}
			} else if (scaleType == IMAGE_SCALE_TYPE_MIDDLE) {
				if (roundedSize > IMAGE_MIDDLE_SCALE) {
					roundedSize = IMAGE_MIDDLE_SCALE;
				}
			} else if (scaleType == IMAGE_SCALE_TYPE_HIGH) {
				if (roundedSize > IMAGE_HIGH_SCALE) {
					roundedSize = IMAGE_HIGH_SCALE;
				}
			}
		}
		
		return roundedSize;
	}

	/**
	 * compute scale factor.
	 * 
	 * @param options
	 * @param minSideLength
	 * @param maxNumOfPixels
	 * @return
	 */
	private int computeInitialSampleSize(BitmapFactory.Options options,
			int minSideLength, int maxNumOfPixels) {
		double w = options.outWidth;
		double h = options.outHeight;
		if(maxNumOfPixels == -1){
			maxNumOfPixels = 800*480;
		}
		if(minSideLength ==-1){
			minSideLength = 480;
		}
		int lowerBound = (maxNumOfPixels == -1) ? 1 : (int) Math.ceil(Math
				.sqrt(w * h / maxNumOfPixels));
		int upperBound = (minSideLength == -1) ? 128 : (int) Math.min(
				Math.floor(w / minSideLength), Math.floor(h / minSideLength));
		if (upperBound < lowerBound) {
			// return the larger one when there is no overlapping zone.
			return lowerBound;
		}
		if ((maxNumOfPixels == -1) && (minSideLength == -1)) {
			return 1;
		} else if (minSideLength == -1) {
			return lowerBound;
		} else {
			return upperBound;
		}
	}

	public interface BitMapInputStream {
		public InputStream getInputStream() throws IOException;
	}
	
	// ///////////////////
	// old start 
	// ///////////////////
	@Deprecated
	public Bitmap loadDrawable(final String imageUrl, final ImageCallback imageCallback, final int scaleType) {
		// ��ǰ�ڴ����Ƿ����
		if (imageCache.containsKey(imageUrl)) {
			WeakReference<Bitmap> softReference = imageCache.get(imageUrl);
			Bitmap bitmap = softReference.get();
			if (bitmap != null && !bitmap.isRecycled()) {
				return bitmap;
			} else {
				imageCache.remove(imageUrl);
			}
		}
		// ��ǰ�ļ��������Ƿ����
		if (mDiskCache.exists(imageUrl)) {
			try {
				Bitmap bitmap = getBitMapFromStream(new BitMapInputStream() {

					@Override
					public InputStream getInputStream() throws IOException {
						return mDiskCache.getInputStream(imageUrl);
					}
				}, IMAGE_MAX_SIZE, scaleType);
				;
				if (bitmap != null && !bitmap.isRecycled()) {
					imageCache.put(imageUrl, new WeakReference<Bitmap>(bitmap));
					return bitmap;
				}
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		final Handler handler = new Handler() {
			public void handleMessage(Message message) {
				imageCallback.imageLoaded((Bitmap) message.obj, imageUrl);
			}
		};
		new Thread() {
			@Override
			public void run() {
				Bitmap bitmap = loadImageFromUrl(imageUrl, scaleType);
				imageCache.put(imageUrl, new WeakReference<Bitmap>(bitmap));
				Message message = handler.obtainMessage(0, bitmap);
				handler.sendMessage(message);
			}
		}.start();
		return null;
	}

	@Deprecated
	private Bitmap getBitMapFromStream(BitMapInputStream inputStream, int maxNumOfPixels, int scaleType)
			throws IOException {
		BitmapFactory.Options opts = new BitmapFactory.Options();
		opts.inJustDecodeBounds = true;
		BitmapFactory.decodeStream(inputStream.getInputStream(), null, opts);
		opts.inSampleSize = computeSampleSize(opts, -1, maxNumOfPixels, scaleType);
		opts.inJustDecodeBounds = false;
		Bitmap bitmap = null;
		try {
			bitmap = BitmapFactory.decodeStream(inputStream.getInputStream(), null, opts);
		} catch (OutOfMemoryError e) {
			e.printStackTrace();
			System.gc();
		}
		return bitmap;
	}

	@Deprecated
	public Bitmap loadImageFromUrl(final String url, int scaleType) {
		Bitmap b = null;
		InputStream is = null;
		try {

			is = application.getApi().getWithStream(url, null);
			if (FileUtil.isSDCARDMounted()) {
				mDiskCache.store(url, new FlushedInputStream(is));
				b = getBitMapFromStream(new BitMapInputStream() {

					@Override
					public InputStream getInputStream() throws IOException {
						return mDiskCache.getInputStream(url);
					}
				}, IMAGE_MAX_SIZE, scaleType);
			} else {
				b = BitmapFactory.decodeStream(new FlushedInputStream(is));
			}
		} catch (MalformedURLException e1) {
			e1.printStackTrace();
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			try {
				if (is != null) {
					is.close();
				}
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		return b;
	}
	public Bitmap getCachedBitMap(String key){
		if (imageCache.containsKey(key)) {
			WeakReference<Bitmap> softReference = imageCache
					.get(key);
			Bitmap bitmap = softReference.get();
			if (bitmap != null && !bitmap.isRecycled()) {
				return bitmap;
			} else {
				imageCache.remove(key);
				return null;
			}
		}
		return null;
	}
	
	public void putCacheBitmap(String key,Bitmap bitmap){
		imageCache.put(key, new WeakReference<Bitmap>(
				bitmap));
	}
	public boolean storeImage(String url){
		try {
			InputStream is = null;
			is = application.getApi().getWithStream(url, null);
			if (mDiskCache.aviable()) {
				mDiskCache.store(url, new FlushedInputStream(is));
			}
			return true;
		} catch (Exception e) {
			CorePreferences.ERROR(e);
			return false;
		}
	}
	// ///////////////////
	// old end
	// ///////////////////
}
